package com.zmm.member.service.impl;

import com.zmm.common.base.model.ResultCode;
import com.zmm.common.constant.NumberConstant;
import com.zmm.common.constant.RedisTimeOutConstant;
import com.zmm.common.exception.handle.BusinessException;
import com.zmm.common.redis.key.RedisKey;
import com.zmm.common.redis.key.StringKey;
import com.zmm.member.dao.CustomerDao;
import com.zmm.member.model.Customer;
import com.zmm.member.service.LoginService;
import com.zmm.util.password.SecurityUtil;
import com.zmm.util.redis.RedisUtil;
import com.zmm.util.time.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author 900045
 * @description:
 * @name LoginServiceImpl
 * @date By 2021-07-26 14:57:44
 */
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {


	@Resource
	private RedisUtil redisUtil;
	
	@Resource
	private CustomerDao customerDao;


	/**
	 * 用户 账户密码 登录 --- 实现
	 * @author: 900045
	 * @date: 2021-08-05 17:41:05
	 * @throws 
	 * @param userName: 
	 * @param password: 
	 * @param ip:   
	 * @return: com.zmm.member.model.Customer
	 **/
	@Override
	public Customer doLogin(String userName, String password, String ip) throws BusinessException {
		RedisKey key = StringKey.LOGIN_FAIL_COUNT.setSuffix(userName);
		// step1. 判断用户是否可以登录
		if (redisUtil.exists(key)) {
			Long sum = redisUtil.increment(key, 0);
			if (sum != null && NumberConstant.TEN < sum) {
				throw new BusinessException(ResultCode.USERNAME_LOGIN_DISABLED);
			}
		}

		// step2.查询用户
		Customer user = customerDao.selectOneCustomerByPhone(userName);
		if (null == user) {
			throw new BusinessException(ResultCode.USER_NOT_EXIST);
		}
		
		// step3.根据规则加密密码
		String encodePwd = SecurityUtil.getStoreLoginPwd(String.valueOf(user.getCustomerId()), password, user.getUserSaltVal());

		if (!encodePwd.equals(user.getCustomerPassword())) {
			Long sum = redisUtil.increment(key,0);
			if (sum >= NumberConstant.TEN) {
				redisUtil.delete(key);
				Long expireTime = RedisTimeOutConstant.S_1800 * 1000L;
				redisUtil.expire(key, expireTime, TimeUnit.MILLISECONDS);
			} else {
				redisUtil.expire(key, DateUtil.getRemainSecondsOneDay(new Date()), TimeUnit.MILLISECONDS);
			}
			log.info("==============当前错误次数:{}=====================", sum);
			throw new BusinessException(ResultCode.PASSWORD_ERROR);
		}
		try {
			customerDao.updateLoginInfo(user.getCustomerId(), ip, DateUtil.getNowTime());
		} catch (Exception e) {
			log.error("登录成功后 更新用户登录信息失败!!!!");
		}
		redisUtil.delete(key);
		return user;
	}

	/**
	 * 验证 -- 短信验证码的 正确性 --- 实现
	 * @author: 900045
	 * @date: 2021-08-05 17:41:15
	 * @throws 
	 * @param phoneNum: 
	 * @param type: 1: 注册 / 2: 登录 / 3: 修改密码
	 * @param verifyCode: 
	 * @return: boolean
	 **/
	@Override
	public boolean captchaSmsVerifyCode(String phoneNum, Integer type, String verifyCode) {
		log.error("验证码验证 -----> phoneNum:[{}] ---- type[1用户注册 2用户登录]:[{}]",phoneNum,type);
		boolean flag = true;
		//校验验证码是否正确
		RedisKey key = StringKey.MOBILE_CODE_KEY_.setSuffix(phoneNum, "_", type.toString());

		Object value = redisUtil.get(key);
		log.error("客户端={},服务端={}",verifyCode, value);
		String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
		Long result = redisUtil.execute(script,key,verifyCode);
		if (result == 0) {
			log.error("短信验证码失效或不正确:");
			flag = false;
		}
		/**
		 * 
		if (null == value || !verifyCode.equals(value.toString())) {
			log.error("短信验证码失效或不正确:客户端={},服务端={}", verifyCode, value)
			flag = false
		} else {
			flag = redisUtil.delete(key)
			if (!flag) {
				log.error("短信验证码已被使用 [{}]", key)
			}
		}
		 */
		return flag;
	}
}
